#include "peripheral.h"
#include "adc.h"
#include "gtim.h"
#include "lpuart.h"
#include "gpio.h"
#include "atim3.h"
#include "work.h"
#include "flash.h"
#include "timer.h"
#include "math.h"
#include "stdlib.h"
#include "stdio.h"
#include "basic.h"
#include "flash.h"

//typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
//#define BANK1_WRITE_START_ADDR  ((uint32_t)0x08008000)
//#define BANK1_WRITE_END_ADDR    ((uint32_t)0x0800C000)	//0x0800C000
//#define FLASH_PAGE_SIZE    ((uint16_t)0x1000)
//typedef void (*iapfun)(void);
//iapfun jump2app;

#define ONE_CH_OTHER_PWM    (10)

static uint8_t u8RxData[20];
static uint8_t u8TxData[]={0x6D,0xAC,0x00,0xFF,0x0A,0x00,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCF,0x68};
static uint8_t u8RxCnt=0;
boolean_t Debug_Mode=0;
uint16_t VDD_Voltage;
uint32_t Boost_Duty=0;
extern uint32_t Trigger_Count,Input_Voltage;
uint32_t USED_DATA;
uint32_t count[4]={1,2,3,4};
uint32_t count1[4]={5,6,7,8};
extern float BAT_Voltage;
extern uint8_t Work_Mode;

uint32_t tubu_duty;
uint32_t freq1;


void App_Clock_Cfg(void)
{
    stc_sysctrl_sysclk_source_init_t   stcSysClkSrc = {0};
    stc_sysctrl_clk_init_t             stcSysClk = {0};

    ///< 系统时钟源初始化
    stcSysClkSrc.u32SysClkSourceType = SYSCTRL_SYSCLK_SOURCE_TYPE_RCH;   //时钟源初始化需要操作RCH
        
    stcSysClkSrc.u32RCHState         = SYSCTRL_RCH_TRIM_48MHz |\
                                       SYSCTRL_RCH_DIV1;            //RCH 设置为1分频  -->48M
    SYSCTRL_SysClkSrcInit(&stcSysClkSrc);   //时钟源初始化
    
    ///< 系统时钟初始化
    stcSysClk.u32ClockType    = SYSCTRL_CLOCKTYPE_SYSCLK |\
                                SYSCTRL_CLOCKTYPE_HCLK   |\
                                SYSCTRL_CLOCKTYPE_PCLK;    //时钟初始化需要操作PLL，HCLK和PCLK
    stcSysClk.u32SysClkSource = SYSCTRL_SYSCLK_SOURCE_RCH; //RCH为系统时钟
    stcSysClk.u32HClkDiv      = SYSCTRL_SYSCLK_HCLK_PRS1;  //HCLK不分频
    stcSysClk.u32PClkDiv      = SYSCTRL_SYSCLK_PCLK_PRS1;  //PCLK不分频
    stcSysClk.u32WaitCycle    = SYSCTRL_FLASH_WAIT_CYCLE2; //设置flash 读等待为2个周期
    
    SYSCTRL_SysClkInit(&stcSysClk);    //时钟初始化
}

void System_ADCInit()
{
		uint32_t AD_Result,Last_Voltage=0;
		stc_adc_cfg_t   stcAdcCfg={0};
		
    /* 第一步：开启ADC/BGR 外设时钟 */
    SYSCTRL_PeriphClkEnable(SYSCTRL_PERIRESET_ADC);
    
    /* 第三步：ADC 初始化配置 */
    stcAdcCfg.u32ClkDiv           = ADC_CLOCK_PCLK_DIV128;     ///< 采样分频-128
    stcAdcCfg.u32SampCycleSel     = ADC_SAMPLINGTIME_12CYCLE;  ///< 采样周期数-12
    stcAdcCfg.u32RefVolSel        = ADC_REF_VOLTAGE_AVCC;      ///< 参考电压选择-AVCC
    stcAdcCfg.u32InputSource      = ADC_EXINPUT_PB05;          ///< 输入信号选择-PA01
    //stcAdcCfg.u32ExtTriggerSource = ADC_EXTTRIGGER_PB03;      ///< 外部触发信号来自-PB03
    ADC_Init(ADC, &stcAdcCfg);
    
    /* 第四步：清除中断标志位 */
    ADC_ClearFlag_EOC(ADC);
    
     /* 第四步：配置中断 */
  //  ADC_EnableIT_EOC(ADC);                ///< 使能EOC中断
  //  EnableNvic(ADC_IRQn, IrqLevel3, TRUE); ///< 使能内核NVIC
}

/*********************************
 * pb01 --ATIMER3--CH1B ---[EMS_--PWM2]
 * PB04 --ATIMER3--CH2B ---[EMS_--PWM2]
****************************/
void System_PWMInit()
{
    stc_gpio_init_t stcCHB4GpioInit = {0};
//    stc_gpio_init_t stcCHB2GpioInit = {0};
		
		uint16_t                          u16CntValue;
    stc_atim3_mode23_cfg_t            stcAtim3BaseCfg  = {0};
//    stc_atim3_m23_compare_cfg_t       stcAtim3ChxaPortCmpCfg = {0};
    stc_atim3_m23_compare_cfg_t       stcAtim3ChxbPortCmpCfg = {0};
    stc_atim3_m23_rcr_cfg_t           stcRcrCfg = {0};
		
//		stc_gtim_init_t    stcInitCfg = {0};
		
    SYSCTRL_PeriphClkEnable(SYSCTRL_PERIRESET_PB);
    
    GPIO_PB04_RESET();     //EMS1_VCC_PWM
    GPIO_PB01_RESET();     // EMS2_VCC_PWM
		
    stcCHB4GpioInit.u32Mode = GPIO_MODE_OUTPUT_PP;
    stcCHB4GpioInit.u32Pin  = GPIO_PIN_04;
    stcCHB4GpioInit.u32Pull = GPIO_PULL_NONE;
    GPIOB_Init(&stcCHB4GpioInit);     //PB04
    
//    GPIO_PB04_AF_ATIM3_CH2B_SET();
		GPIO_PB04_AF_GPIO_SET();

     stcCHB4GpioInit.u32Mode = GPIO_MODE_OUTPUT_PP;
    stcCHB4GpioInit.u32Pin  = GPIO_PIN_01;
    stcCHB4GpioInit.u32Pull = GPIO_PULL_NONE;
    GPIOB_Init(&stcCHB4GpioInit);
    GPIO_PB01_AF_GPIO_SET();    // PB01
		
    SYSCTRL_PeriphClkEnable(SYSCTRL_PERICLK_ATIM3); //ATIM3 外设时钟使能
    
    stcAtim3BaseCfg.u32WorkMode    = ATIM3_M23_M23CR_WORK_MODE_TRIANGULAR; //三角波模式
    stcAtim3BaseCfg.u32CountClkSel = ATIM3_M23_M23CR_CT_PCLK;              //定时器功能，计数时钟为内部PCLK
    stcAtim3BaseCfg.u32PRS         = ATIM3_M23_M23CR_ATIM3CLK_PRS1;        //PCLK
    //stcAtim3BaseCfg.u32CntDir    = ATIM3_M23_M23CR_DIR_UP_CNT;           //向上计数，在三角波模式时只读
    stcAtim3BaseCfg.u32PWMTypeSel  = ATIM3_M23_M23CR_COMP_PWM_INDEPT;       //独立输出PWM
    stcAtim3BaseCfg.u32PWM2sSel    = ATIM3_M23_M23CR_PWM2S_COMPARE_SINGLE_POINT;//单点比较功能
    stcAtim3BaseCfg.u32ShotMode    = ATIM3_M23_M23CR_SHOT_CYCLE;            //循环计数
    stcAtim3BaseCfg.u32URSSel      = ATIM3_M23_M23CR_URS_OV_UND;           //上下溢更新
    ATIM3_Mode23_Init(&stcAtim3BaseCfg);    //ATIM3 的模式23功能初始化
    
    ATIM3_Mode23_ARRSet(24000000/PWM_FREQ);         //设置重载值,并使能缓存
    ATIM3_Mode23_ARR_Buffer_Enable(TRUE);
    
    ATIM3_Mode23_Channel_Compare_Value_Set(ATIM3_COMPARE_CAPTURE_CH1B, Boost_Duty); //设置CH1 通道B比较值
		ATIM3_Mode23_Channel_Compare_Value_Set(ATIM3_COMPARE_CAPTURE_CH2B, Boost_Duty); //设置CH2 通道B比较值

    stcAtim3ChxbPortCmpCfg.u32CHxCmpCap      = ATIM3_M23_CRCHx_CSA_CSB_COMPARE;
    stcAtim3ChxbPortCmpCfg.u32CHxCmpModeCtrl = ATIM3_M23_FLTR_OCMxx_PWM_MODE_2;    //OCREFB输出控制OCMB:PWM模式2(PWM互补模式下也要设置，避免强制输出)
    stcAtim3ChxbPortCmpCfg.u32CHxPolarity    = ATIM3_M23_FLTR_CCPxx_REVERSE_IN_OUT; //正常输出
    stcAtim3ChxbPortCmpCfg.u32CHxCmpBufEn    = ATIM3_M23_CRCHx_BUFEx_ENABLE;       //B通道缓存控制使能
    stcAtim3ChxbPortCmpCfg.u32CHxCmpIntSel   = ATIM3_M23_CRCHx_CISBx_DISABLE_IRQ;  //B通道比较中断控制:无
     
    ATIM3_Mode23_PortOutput_CHxB_Cfg(ATIM3_M23_OUTPUT_CHANNEL_CH1, &stcAtim3ChxbPortCmpCfg);  //比较输出端口CH1B配置
		ATIM3_Mode23_PortOutput_CHxB_Cfg(ATIM3_M23_OUTPUT_CHANNEL_CH2, &stcAtim3ChxbPortCmpCfg);  //比较输出端口CH2B配置
    
    stcRcrCfg.u32EnOverFLowMask = ATIM3_M23_RCR_OVF_IRQ_EVT_CNT_MASK;     //屏蔽上溢重复计数
    stcRcrCfg.u32EnUnderFlowMask = ATIM3_M23_RCR_UND_IRQ_EVT_CNT_ENABLE;   //使能下溢重复计数
    stcRcrCfg.u32RepeatCountNum = 0;
    ATIM3_Mode23_SetRepeatPeriod(&stcRcrCfg);                             //间隔周期设置
    
    u16CntValue = 0;
    ATIM3_Mode23_Cnt16Set(u16CntValue);              //设置计数初值
    
    ATIM3_ClearAllIrqFlag();                         //清中断标志
//    ATIM3_Mode23_EnableIrq(ATIM3_M23_INT_UI);         //使能ATIM3 UEV更新中断
//    EnableNvic(ATIM3_IRQn, IrqLevel0, TRUE);         //ATIM3中断使能
		
		ATIM3_Mode23_Run();
		
		ATIM3_Mode23_Manual_PWM_Output_Enable(TRUE);
}

void App_LpUartPortCfg(void)
{
    stc_gpio_init_t stcGpioInit = {0};
    stc_lpuart_init_t  stcInit = {0};
		
    ///< 外设时钟使能
    SYSCTRL_PeriphClkEnable(SYSCTRL_PERICLK_PA);
    
    stcGpioInit.u32Mode = GPIO_MODE_OUTPUT_PP;
    stcGpioInit.u32Pin  = GPIO_PIN_02;
    stcGpioInit.u32Pull = GPIO_PULL_UP;
    GPIOA_Init(&stcGpioInit);

    stcGpioInit.u32Mode = GPIO_MODE_INPUT;
    stcGpioInit.u32Pin  = GPIO_PIN_01;
    GPIOA_Init(&stcGpioInit);
    
    GPIO_PA02_AF_LPUART0_TXD_SET();
    GPIO_PA01_AF_LPUART0_RXD_SET();
    
    ///<外设模块时钟使能
    SYSCTRL_PeriphClkEnable(SYSCTRL_PERICLK_LPUART0);    
    
    ///<LPUART 初始化
    stcInit.u32StopBits    = LPUART_STOPBITS_1;            ///< 1停止位     
    stcInit.u32Parity      = LPUART_PARITY_NONE;           ///< 偶校验
    stcInit.u32FrameLength = LPUART_FRAME_LEN_8BITS;       ///< 帧长8位
    stcInit.u32TransMode   = LPUART_MODE_TX_RX;            ///< 发送模式
    stcInit.stcBaudRate.u32SclkSrc  = LPUART_CLKSRC_PCLK;  ///< 传输时钟源
    stcInit.stcBaudRate.u32Sclk     = SYSCTRL_GetPCLK();   ///< PCLK获取
    stcInit.stcBaudRate.u32BaudRate = 115200;                ///< 波特率
    LPUART_Init(LPUART0, &stcInit);
		
		LPUART_ClearIrq(LPUART0, LPUART_FLAG_ALL);
    LPUART_EnableIrq(LPUART0, LPUART_INT_RC);
    EnableNvic(LPUART0_IRQn, IrqLevel2, TRUE);
		
//		LPUART_Transmit(LPUART0, TxData, 2, 0xFFFFFF);
//		printf("test\r\n");
//		LPUART_Receive(LPUART0, pu8RxTxBuf, RX_TX_FRAME_LEN, 0xFFFFFF);
}

void LpUart0_IRQHandler(void)
{
		uint32_t ulTemp;
    if (0U != LPUART_GetFlag(LPUART0, LPUART_FLAG_RC))
    {
				if(LPUART_GetFlag(LPUART0, LPUART_FLAG_PE|LPUART_FLAG_FE))
        {
            ///< ����������
            LPUART_ClearIrq(LPUART0, LPUART_FLAG_PE|LPUART_FLAG_FE);
        }
        else
				{
						LPUART_ClearIrq(LPUART0, LPUART_FLAG_RC);
						LPUART_ReceiveIT(LPUART0, (uint8_t *)(&u8RxData[u8RxCnt]));
						if(u8RxData[u8RxCnt]==0xAC&&u8RxData[u8RxCnt-1]==0x6D)
						{
								u8RxCnt=1;
						}
						u8RxCnt++; 
						if(u8RxCnt>=2)
						{
								if((u8RxData[u8RxCnt-2]==0x23)&&(u8RxData[u8RxCnt-1]==0x45))
								{
										u8RxCnt=0;
										Debug_Mode^=1;
										printf("Debug Mode: %d\r\n",Debug_Mode);
								}
						}
						if(u8RxCnt>=18)
						{
								u8RxCnt = 0;
								if ((u8RxData[0]==0x6D)&&(u8RxData[1]==0xAC)&&(u8RxData[6]==0x26)&&(u8RxData[16]==0xA6)&&(u8RxData[17]==0xDA)) //��APP����֡
								{
										LPUART_Transmit(LPUART0, (uint8_t *)u8TxData, 18, 10000);
										//boot para����д���ֵ,֪ͨBootLoaderҪ���³�����
										FLASH_SectorErase(0xF00);
										ulTemp = 0x67890123;
										FLASH_WriteWord(0xF00, &ulTemp, 1);
										NVIC_SystemReset();  //������λMCU
								}                    
						}
				}
    }
		if(LPUART_GetFlag(LPUART0, LPUART_FLAG_TXE))
    {
        LPUART_ClearIrq(LPUART0, LPUART_FLAG_TXE);

		}
}

PUTCHAR_PROTOTYPE
{
    LPUART_Transmit(LPUART0, (uint8_t*)(&ch), 1, 0xFFFFFF);
    return ch;
}

uint16_t ADC_Convert(uint8_t channel)
{
		uint16_t AD_Value,AD_Max,AD_Min;
		uint32_t AD_Sum;
		uint8_t i;
	
		AD_Max = 0x00;
		AD_Min = 0xffff;
		AD_Sum = 0x00;
		ADC_SetInputSource(ADC,channel);
		for(i=0;i<6;i++)
		{
				ADC_StartSingleConversion(ADC);
				while(TRUE != ADC_IsActiveFlag_EOC(ADC));						//�ȴ�ADCת�����
				ADC_ClearFlag_EOC(ADC);          ///< ���EOC�жϱ�־λ
				AD_Value = ADC_GetResult(ADC);					//��ȡADֵ
				if(AD_Value>AD_Max)
				AD_Max = AD_Value;
				if(AD_Value<AD_Min)
				AD_Min = AD_Value;
				AD_Sum+=AD_Value;
		}
		AD_Value = ((AD_Sum - AD_Max - AD_Min)>>2);
		return AD_Value;
}
/*
 * pb01 --ATIMER3--CH1B ---[EMS_--PWM2]
 * PB04 --ATIMER3--CH2B ---[EMS_--PWM1]---对应盆底肌
 * */
void PWM_Driver(uint8_t channel,uint32_t freq,uint32_t duty)
{
		uint32_t duty1;
		if(duty>100){
		  return;
    }

		freq1 = 24000000/freq;
		duty1 = duty*freq1/100;
		switch(channel)
		{
			case PWM_Channel:	
				ATIM3_Mode23_ARRSet(freq1);
				Boost_Duty=duty1;

        tubu_duty = Boost_Duty;

        if(Work_Mode == 1){     // 模式1 ，关闭第1路ems
          ATIM3_Mode23_Channel_Compare_Value_Set(ATIM3_COMPARE_CAPTURE_CH2B, Boost_Duty); // ems1_pwm  盆底肌，较敏感区
        }
        else{
          ATIM3_Mode23_Channel_Compare_Value_Set(ATIM3_COMPARE_CAPTURE_CH2B, Boost_Duty); // ems1_pwm  盆底肌，较敏感区
        }

        if(Work_Mode == 2){     // 模式1 ，关闭第1路ems
          ATIM3_Mode23_Channel_Compare_Value_Set(ATIM3_COMPARE_CAPTURE_CH1B, Boost_Duty*7/10); //设置CH1 通道B比较值 ems2_pwm  臀部
        }
        else{
          ATIM3_Mode23_Channel_Compare_Value_Set(ATIM3_COMPARE_CAPTURE_CH1B, Boost_Duty*7/10); //设置CH1 通道B比较值 ems2_pwm  臀部
        }
				break;
			default:break;
		}
}

void Adc_IRQHandler(void)
{       
		
}

void ATim3_IRQHandler(void)
{
		if(TRUE == ATIM3_GetIntFlag(ATIM3_INT_FLAG_UI))
		{
        if(Work_Mode == 1){     // 模式1 ，关闭第1路ems
          ATIM3_Mode23_Channel_Compare_Value_Set(ATIM3_COMPARE_CAPTURE_CH2B, Boost_Duty); // ems1_pwm  盆底肌，较敏感区
        }
        else{
          ATIM3_Mode23_Channel_Compare_Value_Set(ATIM3_COMPARE_CAPTURE_CH2B, Boost_Duty); // ems1_pwm  盆底肌，较敏感区
        }

        if(Work_Mode == 2){     // 模式1 ，关闭第1路ems
          ATIM3_Mode23_Channel_Compare_Value_Set(ATIM3_COMPARE_CAPTURE_CH1B, Boost_Duty*7/10); //设置CH1 通道B比较值 ems2_pwm 臀部
        }
        else{
          ATIM3_Mode23_Channel_Compare_Value_Set(ATIM3_COMPARE_CAPTURE_CH1B, Boost_Duty*7/10); //设置CH1 通道B比较值 ems2_pwm  臀部
        }
				ATIM3_ClearIrqFlag(ATIM3_INT_CLR_UI);  //���жϱ�־
		}
}
